package com.sc.nft.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.sc.nft.annotation.UserLogin;
import com.sc.nft.annotation.WithoutSign;
import com.sc.nft.controller.request.GetSmsCodeRequest;
import com.sc.nft.controller.request.GetSmsNewCodeRequest;
import com.sc.nft.controller.request.TypeRequest;
import com.sc.nft.controller.request.WalletRequest;
import com.sc.nft.controller.vo.StaticDataVo;
import com.sc.nft.controller.vo.TransferAccountsMinVO;
import com.sc.nft.dao.FilterIncomeListDao;
import com.sc.nft.entity.FilterIncomeList;
import com.sc.nft.entity.StaticData;
import com.sc.nft.entity.vo.MallInvitationCodeVO;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.CheckParameterService;
import com.sc.nft.service.SmsCodeRecordService;
import com.sc.nft.service.StaticDataService;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.Result;
import com.sc.nft.util.ImageCode;
import com.sc.nft.util.RedisUtil;
import com.sc.nft.util.TokenUtil;
import com.sc.nft.util.ValidateCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 服务控制器
 *
 * @author Sun
 * @description 由 Mybatisplus Code Generator 创建
 * @since 2022-05-29 17:37:58
 */
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/staticData")
@Api(tags = "静态资源")
public class StaticDataController {
    private final StaticDataService staticDataService;
    private final CheckParameterService checkParameterService;
    private final SmsCodeRecordService smsCodeRecordService;
    private final RedisUtil redisUtil;
    private final FilterIncomeListDao filterIncomeListDao;
    private final Redisson redisson;

    @ApiOperation(value = "获取注册验证码", notes = "获取注册验证码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/sendRegisteSms", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result sendRegisteSms(@Valid @RequestBody GetSmsCodeRequest getSmsCodeRequest) {
        if (true) {
            throw new GlobalRunTimeException("请升级最新版本");
        }
        HashMap<String, String> map = smsCodeRecordService.sendRegisteSms(getSmsCodeRequest.getUserAccount(),
                getSmsCodeRequest.getType(),
                getSmsCodeRequest.getTypes());
        return Result.success(map);
    }

    @PostMapping(value = "/getPicCode", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取图片验证码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @WithoutSign
    public void getPicCode(@Valid @RequestBody GetSmsCodeRequest request, HttpServletResponse response) throws IOException {
        ImageCode imageCode = ValidateCode.createImageCode();
        redisUtil.set(TokenUtil.getRegisterValidateCode(request.getUserAccount(), request.getType()), imageCode.getCode(), 5);
        ImageIO.write(imageCode.getImage(), "jpeg", response.getOutputStream());
//       # return Result.success();
    }


    @ApiOperation(value = "获取注册验证码(新)", notes = "获取注册验证码(新)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/sendRegisteSmsNew", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result sendRegisteSmsNew(@Valid @RequestBody GetSmsNewCodeRequest request) {

        if (request.getType().intValue() == 1) {

            if (StrUtil.startWithAny(request.getUserAccount(), "192", "162", "165", "167", "170", "171")) {
                return Result.success();
            }
        }
        if (request.getType() != 13) {
            String code = String.valueOf(redisUtil.get(TokenUtil.getRegisterValidateCode(request.getUserAccount(), request.getType())));

            if (StrUtil.equals(code, "null") || !StrUtil.equals(code, request.getVerifyCode())) {
                return Result.fail(ErrorCode.VERIFICATION_ERROR);
            }
        }

        String key = StrUtil.format("{}{}", RedisKeyEnum.MESSAGE_AUTHENTICATION_CODE.getKey(), request.getUserAccount());
        log.info("获取注册验证码(新) key:{}", key);
        RLock lock = redisson.getLock(key);
        HashMap<String, String> map = null;
        boolean b = lock.tryLock();
        try {
            log.info("获取注册验证码(新) 锁获取:{}", b);
            if (!b) {
                throw new GlobalRunTimeException("验证码已发送");
            }
            map = smsCodeRecordService.sendRegisteSms(request.getUserAccount(),
                    request.getType(),
                    request.getTypes());
        } catch (IllegalMonitorStateException e) {
            throw new GlobalRunTimeException("验证码已发送");
        } finally {
            //删除验证码
            redisUtil.del(TokenUtil.getRegisterValidateCode(request.getUserAccount(), request.getType()));
            if (b) {
                lock.unlock();
            }
        }
        return Result.success(map);
    }


    @ApiOperation(value = "获取验证码", notes = "获取验证码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getSmsOtherCode", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result getSmsOtherCode(@Valid @RequestBody GetSmsCodeRequest getSmsCodeRequest) {
        FilterIncomeList filterIncomeList = filterIncomeListDao.getIsTeamIncomeByUserId(UserPool.getUser().getId());
        if (ObjectUtil.isNotNull(filterIncomeList)) {
            HashMap<String, String> map = new HashMap() {{
                put("smsId", "123456");
                put("isSend", "y");
            }};
            return Result.success(map);
        }
        HashMap<String, String> map = smsCodeRecordService.getSmsOtherCode(getSmsCodeRequest.getUserAccount(),
                getSmsCodeRequest.getType(),
                getSmsCodeRequest.getTypes());
        return Result.success(map);
    }

    @ApiOperation(value = "获取七牛图片token", notes = "获取七牛图片token", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getQiniuToken", produces = MediaType.APPLICATION_JSON_VALUE)
    //    @UserLogin
    public Result getQiniuToken() {

        return Result.success(staticDataService.getQiniuToken());
    }

    @ApiOperation(value = "获取静态信息", notes = "获取静态信息", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getStaticData", produces = MediaType.APPLICATION_JSON_VALUE)
//    @UserLogin
    public Result<HashMap<String, String>> getStaticData() {
        HashMap<String, String> staticData = staticDataService.getStaticData();

        return Result.success(staticData);
    }

    @ApiOperation(value = "二级购买须知", notes = "二级购买须知", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getPurchaseNotes", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<String> getPurchaseNotes() {
        StaticData staticData = staticDataService.getByType("second_purchase_notes");
        return Result.success(staticData.getValue());
    }

    @ApiOperation(value = "二级购买须知", notes = "二级购买须知", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getPurchaseNotesWeb", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<StaticDataVo> getPurchaseNotesWeb() {
        StaticData secondPurchaseNotes = staticDataService.getByType("second_purchase_notes");
        StaticDataVo staticDataVo = new StaticDataVo();
        staticDataVo.setType(secondPurchaseNotes.getType());
        staticDataVo.setValue(secondPurchaseNotes.getValue());
        return Result.success(staticDataVo);
    }


    @ApiOperation(value = "转账须知", notes = "转账须知", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getTransferNotes", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<String> getTransferNotes(@Valid @RequestBody WalletRequest request) {
        StaticData staticData = null;
        switch (request.getChannel()) {
            case SAND:
                staticData = staticDataService.getByType("sand_transfer_notes");
                break;
//            case HF:
//                 staticData = staticDataService.getByType("hf_transfer_notes");
//                break;
            case LL:
                staticData = staticDataService.getByType("ll_transfer_notes");
                break;
            case HNA:
                staticData = staticDataService.getByType("hna_transfer_notes");
                break;
            default:
                return Result.fail(ErrorCode.PARAM_ERROR);
        }
        return Result.success(staticData.getValue());
    }


    @ApiOperation(value = "转账最低额度限制", notes = "转账最低额度限制", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/transferAccountsMin", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<TransferAccountsMinVO> transferAccountsMin() {
        StaticData byType = staticDataService.getByType("transfer_accounts_min");
        TransferAccountsMinVO transferAccountsMinVO = new TransferAccountsMinVO();
        StaticData maxValue = staticDataService.getByType("transfer_accounts_max");
        transferAccountsMinVO.setValue(byType.getValue());
        transferAccountsMinVO.setMaxValue(maxValue.getValue());
        return Result.success(transferAccountsMinVO);
    }

    @ApiOperation(value = "商城邀请码", notes = "转账最低额度限制", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/mallInvitationCode", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<MallInvitationCodeVO> mallInvitationCode() {
        StaticData byType = staticDataService.getByType("h5_ip_shop");
        if (BeanUtil.isEmpty(byType)) {
            throw new GlobalRunTimeException("分享链接已结束");
        }
        String value = byType.getValue();
        MallInvitationCodeVO mallInvitationCodeVO = new MallInvitationCodeVO();
        mallInvitationCodeVO.setInvitationCodeUrl(StrUtil.format(value, UserPool.getUser().getInviteCode()));
        return Result.success(mallInvitationCodeVO);
    }

    @PostMapping(value = "/isReadOne", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取是否阅读同意过某个静态数据", notes = "获取是否阅读过某个静态数据", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<Boolean> isReadOne(@RequestBody TypeRequest request) {
        return Result.success(staticDataService.isReadOne(request.getType()));
    }

    @PostMapping(value = "/readAndPass", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "阅读并同意", notes = "阅读并同意", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result readAndAgree(@RequestBody TypeRequest request) {
        staticDataService.readAndAgree(request.getType());
        return Result.success();
    }

}